<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 6.3.0">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" integrity="sha256-Z1K5uhUaJXA7Ll0XrZ/0JhX4lAtZFpT6jkKrEDT0drU=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"example.com","root":"/","images":"/images","scheme":"Muse","darkmode":false,"version":"8.14.1","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":false,"style":null},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"},"path":"/search.xml","localsearch":{"enable":true,"trigger":"auto","top_n_per_article":-1,"unescape":false,"preload":false}}</script><script src="/js/config.js"></script>

    <meta property="og:type" content="website">
<meta property="og:title" content="JsyBlog">
<meta property="og:url" content="http://example.com/page/4/index.html">
<meta property="og:site_name" content="JsyBlog">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="SongyangJi">
<meta name="twitter:card" content="summary">


<link rel="canonical" href="http://example.com/page/4/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":true,"isPost":false,"lang":"zh-CN","comments":"","permalink":"","path":"page/4/index.html","title":""}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>JsyBlog</title>
  








  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <h1 class="site-title">JsyBlog</h1>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="搜索" role="button">
        <i class="fa fa-search fa-fw fa-lg"></i>
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li><li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a></li>
      <li class="menu-item menu-item-search">
        <a role="button" class="popup-trigger"><i class="fa fa-search fa-fw"></i>搜索
        </a>
      </li>
  </ul>
</nav>



  <div class="search-pop-overlay">
    <div class="popup search-popup"><div class="search-header">
  <span class="search-icon">
    <i class="fa fa-search"></i>
  </span>
  <div class="search-input-container">
    <input autocomplete="off" autocapitalize="off" maxlength="80"
           placeholder="搜索..." spellcheck="false"
           type="search" class="search-input">
  </div>
  <span class="popup-btn-close" role="button">
    <i class="fa fa-times-circle"></i>
  </span>
</div>
<div class="search-result-container no-result">
  <div class="search-result-icon">
    <i class="fa fa-spinner fa-pulse fa-5x"></i>
  </div>
</div>

    </div>
  </div>

</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-overview-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">SongyangJi</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">251</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">45</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
          <a href="/tags/">
        <span class="site-state-item-count">109</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>

        </div>
      </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner index posts-expand">

    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2022/12/06/Go%E5%88%B7%E9%A2%98/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2022/12/06/Go%E5%88%B7%E9%A2%98/" class="post-title-link" itemprop="url">Go刷题</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>
      

      <time title="创建时间：2022-12-06 09:17:05 / 修改时间：09:25:45" itemprop="dateCreated datePublished" datetime="2022-12-06T09:17:05+08:00">2022-12-06</time>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <p>字符串</p>
<h1 id="1805-字符串中不同整数的数目"><a href="#1805-字符串中不同整数的数目" class="headerlink" title="1805. 字符串中不同整数的数目"></a>1805. 字符串中不同整数的数目</h1><p><a target="_blank" rel="noopener" href="https://leetcode.cn/problems/number-of-different-integers-in-a-string/solutions/">https://leetcode.cn/problems/number-of-different-integers-in-a-string/solutions/</a></p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">numDifferentIntegers</span><span class="params">(word <span class="type">string</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    cs := []<span class="type">rune</span>(word)</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="built_in">len</span>(cs); i++ &#123;</span><br><span class="line">        <span class="keyword">if</span> !(cs[i] &gt;= <span class="string">&#x27;0&#x27;</span> &amp;&amp; cs[i] &lt;= <span class="string">&#x27;9&#x27;</span>) &#123;</span><br><span class="line">            cs[i] = <span class="string">&#x27; &#x27;</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    word = <span class="type">string</span>(cs)</span><br><span class="line">    splits := strings.Split(word, <span class="string">&quot; &quot;</span>)</span><br><span class="line">    </span><br><span class="line">    f := <span class="function"><span class="keyword">func</span><span class="params">(s <span class="type">string</span>)</span></span> <span class="type">string</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> <span class="built_in">len</span>(s) &gt; <span class="number">1</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> !strings.HasPrefix(s, <span class="string">&quot;0&quot;</span>) &#123;</span><br><span class="line">                <span class="keyword">break</span></span><br><span class="line">            &#125;</span><br><span class="line">            s = strings.TrimPrefix(s, <span class="string">&quot;0&quot;</span>)</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> s</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">for</span> i, s := <span class="keyword">range</span> splits &#123;</span><br><span class="line">        splits[i] = f(s)</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    m := <span class="built_in">make</span>(<span class="keyword">map</span>[<span class="type">string</span>]<span class="type">int</span>)</span><br><span class="line">    <span class="keyword">for</span> _, s := <span class="keyword">range</span> splits &#123;</span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">len</span>(s) &gt; <span class="number">0</span> &#123;</span><br><span class="line">            m[s]++</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">len</span>(m)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<p>一次遍历，且原地完成</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">numDifferentIntegers</span><span class="params">(word <span class="type">string</span>)</span></span> <span class="type">int</span> &#123;</span><br><span class="line">    s := <span class="keyword">map</span>[<span class="type">string</span>]<span class="type">bool</span>&#123;&#125;</span><br><span class="line">    n := <span class="built_in">len</span>(word)</span><br><span class="line">    p1 := <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> p1 &lt; n &amp;&amp; !unicode.IsDigit(<span class="type">rune</span>(word[p1])) &#123;</span><br><span class="line">            p1++</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> p1 == n &#123;</span><br><span class="line">            <span class="keyword">break</span></span><br><span class="line">        &#125;</span><br><span class="line">        p2 := p1</span><br><span class="line">        <span class="keyword">for</span> p2 &lt; n &amp;&amp; unicode.IsDigit(<span class="type">rune</span>(word[p2])) &#123;</span><br><span class="line">            p2++</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">for</span> p2-p1 &gt; <span class="number">1</span> &amp;&amp; word[p1] == <span class="string">&#x27;0&#x27;</span> &#123; <span class="comment">// 去除前导 0</span></span><br><span class="line">            p1++</span><br><span class="line">        &#125;</span><br><span class="line">        s[word[p1:p2]] = <span class="literal">true</span></span><br><span class="line">        p1 = p2</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">len</span>(s)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2022/12/03/Kitex01/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2022/12/03/Kitex01/" class="post-title-link" itemprop="url">Kitex入门</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2022-12-03 23:59:15" itemprop="dateCreated datePublished" datetime="2022-12-03T23:59:15+08:00">2022-12-03</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2022-12-09 02:24:24" itemprop="dateModified" datetime="2022-12-09T02:24:24+08:00">2022-12-09</time>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="thrift入门"><a href="#thrift入门" class="headerlink" title="thrift入门"></a>thrift入门</h1><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew install thrift</span><br></pre></td></tr></table></figure>

<h2 id="编写thrift文件"><a href="#编写thrift文件" class="headerlink" title="编写thrift文件"></a>编写thrift文件</h2><p><a target="_blank" rel="noopener" href="https://thrift.apache.org/docs/idl">thrift语法</a></p>
<p>Goland 插件：Thrift Support</p>
<p><code>User.thrift</code></p>
<figure class="highlight thrift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">namespace</span> go Sample <span class="comment">// Sample对应go的module名</span></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">User</span> </span>&#123;</span><br><span class="line">    <span class="number">1</span>:<span class="keyword">required</span> <span class="type">i32</span> id;</span><br><span class="line">    <span class="number">2</span>:<span class="keyword">required</span> <span class="type">string</span> name;</span><br><span class="line">    <span class="number">3</span>:<span class="keyword">required</span> <span class="type">string</span> avatar;</span><br><span class="line">    <span class="number">4</span>:<span class="keyword">required</span> <span class="type">string</span> address;</span><br><span class="line">    <span class="number">5</span>:<span class="keyword">required</span> <span class="type">string</span> mobile;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">UserList</span> </span>&#123;</span><br><span class="line">    <span class="number">1</span>:<span class="keyword">required</span> <span class="type">list</span>&lt;User&gt; userList;</span><br><span class="line">    <span class="number">2</span>:<span class="keyword">required</span> <span class="type">i32</span> page;</span><br><span class="line">    <span class="number">3</span>:<span class="keyword">required</span> <span class="type">i32</span> limit;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<p><code>Service.thrift</code></p>
<figure class="highlight thrift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">include <span class="string">&quot;User.thrift&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> go Sample</span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="type">map</span>&lt;<span class="type">string</span>, <span class="type">string</span>&gt; Data</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Response</span> </span>&#123;</span><br><span class="line">    <span class="number">1</span>:<span class="keyword">required</span> <span class="type">i32</span> errCode; <span class="comment">// 错误码</span></span><br><span class="line">    <span class="number">2</span>:<span class="keyword">required</span> <span class="type">string</span> errMsg; <span class="comment">// 错误信息</span></span><br><span class="line">    <span class="number">3</span>:<span class="keyword">required</span> Data data;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//定义服务</span></span><br><span class="line"><span class="class"><span class="keyword">service</span> <span class="title">Greeter</span> </span>&#123;</span><br><span class="line">    Response SayHello(</span><br><span class="line">        <span class="number">1</span>:<span class="keyword">required</span> User.User user</span><br><span class="line">    )</span><br><span class="line"></span><br><span class="line">    Response GetUser(</span><br><span class="line">        <span class="number">1</span>:<span class="keyword">required</span> <span class="type">i32</span> uid</span><br><span class="line">    )</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h2 id="使用thrift脚手架"><a href="#使用thrift脚手架" class="headerlink" title="使用thrift脚手架"></a>使用thrift脚手架</h2><p>使用<code>thrift -r -v --gen go idl/Service.thrift</code>根据idl文件生成go代码。</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">jisongyang@SongyangJi-MacBookAir thrift_sample % thrift -r -v --gen go idl/Service.thrift</span><br><span class="line">Scanning /Users/jisongyang/GolandProjects/thrift_sample/idl/Service.thrift <span class="keyword">for</span> includes</span><br><span class="line">Scanning /Users/jisongyang/GolandProjects/thrift_sample/idl/User.thrift <span class="keyword">for</span> includes</span><br><span class="line">Parsing /Users/jisongyang/GolandProjects/thrift_sample/idl/User.thrift <span class="keyword">for</span> types</span><br><span class="line">Parsing /Users/jisongyang/GolandProjects/thrift_sample/idl/Service.thrift <span class="keyword">for</span> types</span><br><span class="line">Program: /Users/jisongyang/GolandProjects/thrift_sample/idl/User.thrift</span><br><span class="line">Generating <span class="string">&quot;go&quot;</span></span><br><span class="line">Program: /Users/jisongyang/GolandProjects/thrift_sample/idl/Service.thrift</span><br><span class="line">Generating <span class="string">&quot;go&quot;</span></span><br></pre></td></tr></table></figure>

<p>目录结构</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">.</span><br><span class="line">├── client_test.go</span><br><span class="line">├── gen-go  # thrift脚手架生成的目录</span><br><span class="line">│   └── Sample</span><br><span class="line">│       ├── GoUnusedProtection__.go</span><br><span class="line">│       ├── Service-consts.go</span><br><span class="line">│       ├── Service.go</span><br><span class="line">│       ├── User-consts.go</span><br><span class="line">│       ├── User.go</span><br><span class="line">│       └── greeter-remote</span><br><span class="line">│           └── greeter-remote.go</span><br><span class="line">├── go.mod</span><br><span class="line">├── go.sum</span><br><span class="line">├── idl # 自己编写的idl文件</span><br><span class="line">│   ├── Service.thrift</span><br><span class="line">│   └── User.thrift</span><br><span class="line">└── main.go</span><br></pre></td></tr></table></figure>



<h2 id="server端实现interface"><a href="#server端实现interface" class="headerlink" title="server端实现interface"></a>server端实现interface</h2><p>这是thrift生成的</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> Greeter <span class="keyword">interface</span> &#123;</span><br><span class="line">  <span class="comment">// Parameters:</span></span><br><span class="line">  <span class="comment">//  - User</span></span><br><span class="line">  SayHello(ctx context.Context, user *User) (_r *Response, _err <span class="type">error</span>)</span><br><span class="line">  <span class="comment">// Parameters:</span></span><br><span class="line">  <span class="comment">//  - UID</span></span><br><span class="line">  GetUser(ctx context.Context, uid <span class="type">int32</span>) (_r *Response, _err <span class="type">error</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>server端里去实现：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//定义服务</span></span><br><span class="line"><span class="keyword">type</span> Greeter <span class="keyword">struct</span> &#123;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//实现IDL里定义的接口</span></span><br><span class="line"><span class="comment">//SayHello</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(this *Greeter)</span></span> SayHello(ctx context.Context, u *Sample.User) (r *Sample.Response, err <span class="type">error</span>) &#123;</span><br><span class="line">    strJson, _ := json.Marshal(u)</span><br><span class="line">    <span class="keyword">return</span> &amp;Sample.Response&#123;ErrCode: <span class="number">0</span>, ErrMsg: <span class="string">&quot;success&quot;</span>, Data: <span class="keyword">map</span>[<span class="type">string</span>]<span class="type">string</span>&#123;<span class="string">&quot;User&quot;</span>: <span class="type">string</span>(strJson)&#125;&#125;, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//GetUser</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(this *Greeter)</span></span> GetUser(ctx context.Context, uid <span class="type">int32</span>) (r *Sample.Response, err <span class="type">error</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span> &amp;Sample.Response&#123;ErrCode: <span class="number">1</span>, ErrMsg: <span class="string">&quot;user not exist.&quot;</span>&#125;, <span class="literal">nil</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>





<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line">   </span><br><span class="line"><span class="comment">//buffered</span></span><br><span class="line"><span class="keyword">var</span> transportFactory thrift.TTransportFactory</span><br><span class="line"><span class="keyword">if</span> *buffered &#123;</span><br><span class="line">    transportFactory = thrift.NewTBufferedTransportFactory(<span class="number">8192</span>)</span><br><span class="line">&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    transportFactory = thrift.NewTTransportFactory()</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//framed</span></span><br><span class="line"><span class="keyword">if</span> *framed &#123;</span><br><span class="line">    transportFactory = thrift.NewTFramedTransportFactory(transportFactory)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//handler</span></span><br><span class="line">handler := &amp;Greeter&#123;&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//transport,no secure</span></span><br><span class="line"><span class="keyword">var</span> err <span class="type">error</span></span><br><span class="line"><span class="keyword">var</span> transport thrift.TServerTransport</span><br><span class="line">transport, err = thrift.NewTServerSocket(*addr)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">    fmt.Println(<span class="string">&quot;error running server:&quot;</span>, err)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//processor</span></span><br><span class="line">processor := Sample.NewGreeterProcessor(handler) <span class="comment">// 关键</span></span><br><span class="line"></span><br><span class="line">fmt.Println(<span class="string">&quot;Starting the simple server... on &quot;</span>, *addr)</span><br><span class="line"></span><br><span class="line"><span class="comment">//start tcp server</span></span><br><span class="line">server := thrift.NewTSimpleServer4(processor, transport, transportFactory, protocolFactory)</span><br><span class="line">err = server.Serve()</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">    fmt.Println(<span class="string">&quot;error running server:&quot;</span>, err)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h2 id="client端"><a href="#client端" class="headerlink" title="client端"></a>client端</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> ctx = context.Background()</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">GetClient</span><span class="params">()</span></span> *Sample.GreeterClient &#123;</span><br><span class="line">    addr := <span class="string">&quot;:9090&quot;</span></span><br><span class="line">    <span class="keyword">var</span> transport thrift.TTransport</span><br><span class="line">    <span class="keyword">var</span> err <span class="type">error</span></span><br><span class="line">    transport, err = thrift.NewTSocket(addr)</span><br><span class="line">    <span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">        fmt.Println(<span class="string">&quot;Error opening socket:&quot;</span>, err)</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//protocol</span></span><br><span class="line">    <span class="keyword">var</span> protocolFactory thrift.TProtocolFactory</span><br><span class="line">    protocolFactory = thrift.NewTBinaryProtocolFactoryDefault()</span><br><span class="line">    </span><br><span class="line">    <span class="comment">//no buffered</span></span><br><span class="line">    <span class="keyword">var</span> transportFactory thrift.TTransportFactory</span><br><span class="line">    transportFactory = thrift.NewTTransportFactory()</span><br><span class="line">    </span><br><span class="line">    transport, err = transportFactory.GetTransport(transport)</span><br><span class="line">    <span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">        fmt.Println(<span class="string">&quot;error running client:&quot;</span>, err)</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">if</span> err := transport.Open(); err != <span class="literal">nil</span> &#123;</span><br><span class="line">        fmt.Println(<span class="string">&quot;error running client:&quot;</span>, err)</span><br><span class="line">    &#125;</span><br><span class="line">    </span><br><span class="line">    iprot := protocolFactory.GetProtocol(transport)</span><br><span class="line">    oprot := protocolFactory.GetProtocol(transport)</span><br><span class="line">    </span><br><span class="line">    client := Sample.NewGreeterClient(thrift.NewTStandardClient(iprot, oprot)) <span class="comment">// 关键</span></span><br><span class="line">    <span class="keyword">return</span> client</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//GetUser</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">TestGetUser</span><span class="params">(t *testing.T)</span></span> &#123;</span><br><span class="line">    client := GetClient()</span><br><span class="line">    rep, err := client.GetUser(ctx, <span class="number">100</span>)</span><br><span class="line">    <span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">        t.Errorf(<span class="string">&quot;thrift err: %v\n&quot;</span>, err)</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        t.Logf(<span class="string">&quot;Recevied: %v\n&quot;</span>, rep)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>






<blockquote>
<p>Reference</p>
<p><a target="_blank" rel="noopener" href="https://thrift.apache.org/">https://thrift.apache.org/</a></p>
<p><a target="_blank" rel="noopener" href="https://thrift.apache.org/docs/idl">thrift语法</a></p>
</blockquote>
<h1 id="Kitex"><a href="#Kitex" class="headerlink" title="Kitex"></a>Kitex</h1><p>关于kite的介绍和微服务rpc的基本概念就不写了，直接上操作。</p>
<h2 id="安装-1"><a href="#安装-1" class="headerlink" title="安装"></a>安装</h2><ol>
<li>安装 kitex：<code>go install github.com/cloudwego/kitex/tool/cmd/kitex@latest</code></li>
<li>安装 thriftgo：<code>go install github.com/cloudwego/thriftgo@latest</code></li>
</ol>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">jisongyang@SongyangJi-MacBookAir kitex_echo % kitex --version</span><br><span class="line">v0.4.3</span><br><span class="line">jisongyang@SongyangJi-MacBookAir kitex_echo % thriftgo --version</span><br><span class="line">thriftgo 0.2.4</span><br></pre></td></tr></table></figure>

<blockquote>
<p>有了thriftgo无需安装thrift了。</p>
</blockquote>
<blockquote>
<p>这里可以直接创建目录，用kitex生成项目，也可以先创建go项目再进去编写idl。</p>
</blockquote>
<h2 id="编写IDL"><a href="#编写IDL" class="headerlink" title="编写IDL"></a>编写IDL</h2><p>echo.thrift</p>
<figure class="highlight thrift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">namespace</span> go api</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Request</span> </span>&#123;</span><br><span class="line">  <span class="number">1</span>: <span class="type">string</span> message</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Response</span> </span>&#123;</span><br><span class="line">  <span class="number">1</span>: <span class="type">string</span> message</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">service</span> <span class="title">Echo</span> </span>&#123;</span><br><span class="line">    Response echo(<span class="number">1</span>: Request req)</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>



<h2 id="生成-echo-服务代码"><a href="#生成-echo-服务代码" class="headerlink" title="生成 echo 服务代码"></a>生成 echo 服务代码</h2><p>命令：<code>kitex -module kitex_echo -service p.s.m echo.thrift</code></p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">jisongyang@SongyangJi-MacBookAir kitex_echo % kitex -module kitex_echo -service p.s.m echo.thrift</span><br><span class="line">jisongyang@SongyangJi-MacBookAir kitex_echo % tree</span><br><span class="line">.</span><br><span class="line">├── build.sh</span><br><span class="line">├── echo.thrift</span><br><span class="line">├── go.mod</span><br><span class="line">├── handler.go</span><br><span class="line">├── kitex_gen</span><br><span class="line">│   └── api # idl中go的namespace</span><br><span class="line">│       ├── echo # idl的文件名</span><br><span class="line">│       │   ├── client.go</span><br><span class="line">│       │   ├── echo.go</span><br><span class="line">│       │   ├── invoker.go</span><br><span class="line">│       │   └── server.go</span><br><span class="line">│       ├── echo.go</span><br><span class="line">│       ├── k-consts.go</span><br><span class="line">│       └── k-echo.go</span><br><span class="line">├── main.go</span><br><span class="line">└── script</span><br><span class="line">    └── bootstrap.sh</span><br><span class="line"></span><br><span class="line">4 directories, 13 files</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p><a target="_blank" rel="noopener" href="https://www.cloudwego.io/zh/docs/kitex/tutorials/code-gen/code_generation/">代码生成</a></p>
<ul>
<li>-service service_name<br>使用该选项时，kitex 会生成构建一个服务的脚手架代码，参数 <code>service_name</code> 给出启动时服务自身的名字，通常其值取决于使用 Kitex 框架时搭配的服务注册和服务发现功能。</li>
</ul>
<p>如果不指定 -service 参数，那么生成的只有 kitex_gen 目录。</p>
<ul>
<li>-module module_name<br>该参数用于指定生成代码所属的 Go 模块，会影响生成代码里的 import path。<br>如果当前目录是在 $GOPATH&#x2F;src 下的一个目录，那么可以不指定该参数；kitex 会使用 $GOPATH&#x2F;src 开始的相对路径作为 import path 前缀。例如，在$GOPATH&#x2F;src&#x2F;example.com&#x2F;hello&#x2F;world 下执行 kitex，那么 kitex_gen&#x2F;example_package&#x2F;example_package.go 在其他代码代码里的 import path 会是 example.com&#x2F;hello&#x2F;world&#x2F;kitex_gen&#x2F;example_package。<br>如果当前目录不在 $GOPATH&#x2F;src 下，那么必须指定该参数。<br>如果指定了 -module 参数，那么 kitex 会从当前目录开始往上层搜索 go.mod 文件<br>如果不存在 go.mod 文件，那么 kitex 会调用 go mod init 生成 go.mod；<br>如果存在 go.mod 文件，那么 kitex 会检查 -module 的参数和 go.mod 里的模块名字是否一致，如果不一致则会报错退出；<br>最后，go.mod 的位置及其模块名字会决定生成代码里的 import path。</li>
</ul>
<blockquote>
<p>Another example</p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">.</span><br><span class="line">├── build.sh                     // 服务的构建脚本，会创建一个名为 output 的目录并生成启动服务所需的文件到里面</span><br><span class="line">├── handler.go                   // 用户在该文件里实现 IDL service 定义的方法</span><br><span class="line">├── kitex_gen                    // IDL 内容相关的生成代码</span><br><span class="line">│   ├── base                     // base.thrift 的生成代码</span><br><span class="line">│   │   ├── base.go              // thriftgo 的产物，包含 base.thrift 定义的内容的 go 代码</span><br><span class="line">│   │   └── k-base.go            // kitex 在 thriftgo 的产物之外生成的代码</span><br><span class="line">│   └── demo                     // demo.thrift 的生成代码</span><br><span class="line">│       ├── demo.go              // thriftgo 的产物，包含 demo.thrift 定义的内容的 go 代码</span><br><span class="line">│       ├── k-demo.go            // kitex 在 thriftgo 的产物之外生成的代码</span><br><span class="line">│       └── demoservice          // kitex 为 demo.thrift 里定义的 demo service 生成的代码</span><br><span class="line">│           ├── demoservice.go   // 提供了 client.go 和 server.go 共用的一些定义</span><br><span class="line">│           ├── client.go        // 提供了 NewClient API</span><br><span class="line">│           └── server.go        // 提供了 NewServer API</span><br><span class="line">├── main.go                      // 程序入口</span><br><span class="line">└── script                       // 构建脚本</span><br><span class="line">    └── bootstrap.sh             // 服务的启动脚本，会被 build.sh 拷贝至 output 下</span><br></pre></td></tr></table></figure>





<h3 id="一个bug——not-enough-arguments-in-call-to-t-tProt-xxx"><a href="#一个bug——not-enough-arguments-in-call-to-t-tProt-xxx" class="headerlink" title="一个bug——not enough arguments in call to t.tProt.xxx"></a>一个bug——not enough arguments in call to t.tProt.xxx</h3><p>根本原因是thrift在git上的go包更新了增加对go 1.7中的http.request + context的用法，部分函数中增加了context参数；但是thriftgo生成的go代码是版本较低的。</p>
<p>所以解决方案就是要么使用最新的thriftgo（目前好像develop版本可以），要么降低<code>github.com/apache/thrif</code>的版本。</p>
<p>亲测，将版本降低到v0.13.0是可以的。</p>
<h2 id="client端-1"><a href="#client端-1" class="headerlink" title="client端"></a>client端</h2><p>值得一提的是，这里直接使用了服务端生成的go代码，这是可以的也是应该的。</p>
<p>如果如果是其他语言的话，就必须要在generate code一下了。</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line">    <span class="string">&quot;context&quot;</span></span><br><span class="line">    <span class="string">&quot;log&quot;</span></span><br><span class="line">    <span class="string">&quot;time&quot;</span></span><br><span class="line">    </span><br><span class="line">    <span class="string">&quot;github.com/cloudwego/kitex/client&quot;</span></span><br><span class="line">    <span class="string">&quot;github.com/cloudwego/kitex/client/callopt&quot;</span></span><br><span class="line">    <span class="string">&quot;kitex_echo/kitex_gen/api&quot;</span></span><br><span class="line">    <span class="string">&quot;kitex_echo/kitex_gen/api/echo&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">    c, err := echo.NewClient(<span class="string">&quot;p.s.m&quot;</span>, client.WithHostPorts(<span class="string">&quot;0.0.0.0:8888&quot;</span>))</span><br><span class="line">    <span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">        log.Fatal(err)</span><br><span class="line">    &#125;</span><br><span class="line">    req := &amp;api.Request&#123;Message: <span class="string">&quot;helloworld from jsy&quot;</span>&#125;</span><br><span class="line">    resp, err := c.Echo(context.Background(), req, callopt.WithRPCTimeout(<span class="number">3</span>*time.Second))</span><br><span class="line">    <span class="keyword">if</span> err != <span class="literal">nil</span> &#123;</span><br><span class="line">        log.Fatal(err)</span><br><span class="line">    &#125;</span><br><span class="line">    log.Println(resp)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<p>Go.mod</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">module kite_echo_client</span><br><span class="line"></span><br><span class="line"><span class="keyword">go</span> <span class="number">1.18</span></span><br><span class="line"></span><br><span class="line">require (</span><br><span class="line">	github.com/cloudwego/kitex v0<span class="number">.4</span><span class="number">.3</span></span><br><span class="line">	kitex_echo v0<span class="number">.0</span><span class="number">.0</span><span class="number">-00010101000000</span><span class="number">-000000000000</span> <span class="comment">// 这个服务端的module还没推送到git remote</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">require (</span><br><span class="line">	github.com/apache/thrift v0<span class="number">.13</span><span class="number">.0</span> <span class="comment">// indirect</span></span><br><span class="line">	github.com/bytedance/gopkg v0<span class="number">.0</span><span class="number">.0</span><span class="number">-20220531084716</span><span class="number">-665</span>b4f21126f <span class="comment">// indirect</span></span><br><span class="line">	github.com/chenzhuoyu/iasm v0<span class="number">.0</span><span class="number">.0</span><span class="number">-20220818063314</span><span class="number">-28</span>c361dae733 <span class="comment">// indirect</span></span><br><span class="line">	github.com/choleraehyq/pid v0<span class="number">.0</span><span class="number">.15</span> <span class="comment">// indirect</span></span><br><span class="line">	github.com/cloudwego/fastpb v0<span class="number">.0</span><span class="number">.2</span> <span class="comment">// indirect</span></span><br><span class="line">	github.com/cloudwego/frugal v0<span class="number">.1</span><span class="number">.3</span> <span class="comment">// indirect</span></span><br><span class="line">	github.com/cloudwego/netpoll v0<span class="number">.2</span><span class="number">.6</span> <span class="comment">// indirect</span></span><br><span class="line">	github.com/cloudwego/thriftgo v0<span class="number">.2</span><span class="number">.1</span> <span class="comment">// indirect</span></span><br><span class="line">	github.com/golang/protobuf v1<span class="number">.5</span><span class="number">.2</span> <span class="comment">// indirect</span></span><br><span class="line">	github.com/google/pprof v0<span class="number">.0</span><span class="number">.0</span><span class="number">-20220608213341</span>-c488b8fa1db3 <span class="comment">// indirect</span></span><br><span class="line">	github.com/jhump/protoreflect v1<span class="number">.8</span><span class="number">.2</span> <span class="comment">// indirect</span></span><br><span class="line">	github.com/json-iterator/<span class="keyword">go</span> v1<span class="number">.1</span><span class="number">.12</span> <span class="comment">// indirect</span></span><br><span class="line">	github.com/modern-<span class="keyword">go</span>/concurrent v0<span class="number">.0</span><span class="number">.0</span><span class="number">-20180228061459</span>-e0a39a4cb421 <span class="comment">// indirect</span></span><br><span class="line">	github.com/modern-<span class="keyword">go</span>/reflect2 v1<span class="number">.0</span><span class="number">.2</span> <span class="comment">// indirect</span></span><br><span class="line">	github.com/oleiade/lane v1<span class="number">.0</span><span class="number">.1</span> <span class="comment">// indirect</span></span><br><span class="line">	github.com/tidwall/gjson v1<span class="number">.9</span><span class="number">.3</span> <span class="comment">// indirect</span></span><br><span class="line">	github.com/tidwall/match v1<span class="number">.1</span><span class="number">.1</span> <span class="comment">// indirect</span></span><br><span class="line">	github.com/tidwall/pretty v1<span class="number">.2</span><span class="number">.0</span> <span class="comment">// indirect</span></span><br><span class="line">	golang.org/x/arch v0<span class="number">.0</span><span class="number">.0</span><span class="number">-20220722155209</span><span class="number">-00200</span>b7164a7 <span class="comment">// indirect</span></span><br><span class="line">	golang.org/x/net v0<span class="number">.0</span><span class="number">.0</span><span class="number">-20210614182718</span><span class="number">-04</span>defd469f4e <span class="comment">// indirect</span></span><br><span class="line">	golang.org/x/sync v0<span class="number">.0</span><span class="number">.0</span><span class="number">-20210220032951</span><span class="number">-036812</span>b2e83c <span class="comment">// indirect</span></span><br><span class="line">	golang.org/x/sys v0<span class="number">.0</span><span class="number">.0</span><span class="number">-20220817070843</span><span class="number">-5</span>a390386f1f2 <span class="comment">// indirect</span></span><br><span class="line">	golang.org/x/text v0<span class="number">.3</span><span class="number">.6</span> <span class="comment">// indirect</span></span><br><span class="line">	google.golang.org/genproto v0<span class="number">.0</span><span class="number">.0</span><span class="number">-20210513213006</span>-bf773b8c8384 <span class="comment">// indirect</span></span><br><span class="line">	google.golang.org/protobuf v1<span class="number">.28</span><span class="number">.0</span> <span class="comment">// indirect</span></span><br><span class="line">	gopkg.in/yaml.v3 v3<span class="number">.0</span><span class="number">.1</span> <span class="comment">// indirect</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">replace kitex_echo =&gt; ../kitex_echo <span class="comment">// 直接替换为本地目录</span></span><br></pre></td></tr></table></figure>







<p><a target="_blank" rel="noopener" href="https://www.cloudwego.io/zh/docs/kitex/">https://www.cloudwego.io/zh/docs/kitex/</a></p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2022/12/03/GoLang-%E6%B5%8B%E8%AF%95/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2022/12/03/GoLang-%E6%B5%8B%E8%AF%95/" class="post-title-link" itemprop="url">GoLang-测试</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2022-12-03 23:12:51" itemprop="dateCreated datePublished" datetime="2022-12-03T23:12:51+08:00">2022-12-03</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2022-12-04 19:35:17" itemprop="dateModified" datetime="2022-12-04T19:35:17+08:00">2022-12-04</time>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="Go-Testing"><a href="#Go-Testing" class="headerlink" title="Go-Testing"></a>Go-Testing</h1><ol>
<li>测试代码须放在包以<code>_test.go</code>结尾的文件中。</li>
<li>测试函数以<code>Test</code>为前缀。</li>
<li>测试命令（<code>go test</code>）忽略以”_”或”.”开头的测试文件。</li>
<li>正常的编译操作(<code>go build</code>、<code>go install</code>)会忽略测试文件</li>
</ol>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2022/12/01/GoLang-Module/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2022/12/01/GoLang-Module/" class="post-title-link" itemprop="url">GoLang-Module</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2022-12-01 00:24:38" itemprop="dateCreated datePublished" datetime="2022-12-01T00:24:38+08:00">2022-12-01</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2022-12-09 02:35:05" itemprop="dateModified" datetime="2022-12-09T02:35:05+08:00">2022-12-09</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Go/" itemprop="url" rel="index"><span itemprop="name">Go</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="Go-Mod-模式"><a href="#Go-Mod-模式" class="headerlink" title="Go Mod 模式"></a>Go Mod 模式</h1><p>Go Modules 在 Go 1.11 和 Go 1.12 中有三个模式，根据环境变量 <code>GO111MODULE</code>进行配置：</p>
<h2 id="GOPATH-模式（GO111MODULE-x3D-off）"><a href="#GOPATH-模式（GO111MODULE-x3D-off）" class="headerlink" title="GOPATH 模式（GO111MODULE&#x3D;off）"></a>GOPATH 模式（GO111MODULE&#x3D;off）</h2><p>Go 编译器从不使用 Go Mod。而会查找 vendor 目录和 GOPATH 以查找依赖项。</p>
<h2 id="Go-Modules-模式（-GO111MODULE-x3D-on）"><a href="#Go-Modules-模式（-GO111MODULE-x3D-on）" class="headerlink" title="Go Modules 模式（ GO111MODULE&#x3D;on）"></a>Go Modules 模式（ GO111MODULE&#x3D;on）</h2><p>Go 编译器只使用 Go Mod，GOPATH不再作为导入目录，但它还是会把下载的依赖储存在 GOPATH&#x2F;pkg&#x2F;mod 中，也会把 go install 命令的结果放在 GOPATH&#x2F;bin 中。</p>
<h2 id="缺省模式（未设置该环境变量或-GO111MODULE-x3D-auto）"><a href="#缺省模式（未设置该环境变量或-GO111MODULE-x3D-auto）" class="headerlink" title="缺省模式（未设置该环境变量或 GO111MODULE&#x3D;auto）"></a>缺省模式（未设置该环境变量或 GO111MODULE&#x3D;auto）</h2><p>Go 编译器在同时满足以下两个条件时使用 Go Mod</p>
<p>1.当前目录不在 GOPATH&#x2F;src&#x2F; 下；<br>2.在当前目录或上层目录中存在 go.mod 文件；</p>
<p>Go 1.13 及1.13以后版本默认使用 Go Mod 模式</p>
<h1 id="依赖管理命令-go-get-x2F-install、go-mod-tidy、download"><a href="#依赖管理命令-go-get-x2F-install、go-mod-tidy、download" class="headerlink" title="依赖管理命令 go get&#x2F;install、go mod tidy、download"></a>依赖管理命令 go get&#x2F;install、go mod tidy、download</h1><h1 id="Go-Module的发布、导入"><a href="#Go-Module的发布、导入" class="headerlink" title="Go Module的发布、导入"></a>Go Module的发布、导入</h1><p><a target="_blank" rel="noopener" href="https://zhuanlan.zhihu.com/p/109828249">https://zhuanlan.zhihu.com/p/109828249</a></p>
<blockquote>
<p>参考文章<br><a target="_blank" rel="noopener" href="https://www.topgoer.com/%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/%E9%85%8D%E7%BD%AEgopath.html">https://www.topgoer.com/%E5%BC%80%E5%8F%91%E7%8E%AF%E5%A2%83/%E9%85%8D%E7%BD%AEgopath.html</a></p>
<p><a target="_blank" rel="noopener" href="https://go.dev/blog/using-go-modules">https://go.dev/blog/using-go-modules</a></p>
<p><a target="_blank" rel="noopener" href="https://blog.csdn.net/m0_63044390/article/details/123984873">https://blog.csdn.net/m0_63044390/article/details/123984873</a></p>
<p><a target="_blank" rel="noopener" href="https://www.topgoer.com/%E5%85%B6%E4%BB%96/%E4%BE%9D%E8%B5%96%E7%AE%A1%E7%90%86.html">https://www.topgoer.com/%E5%85%B6%E4%BB%96/%E4%BE%9D%E8%B5%96%E7%AE%A1%E7%90%86.html</a></p>
<p><a target="_blank" rel="noopener" href="https://www.jianshu.com/p/04dd0d386df2">https://www.jianshu.com/p/04dd0d386df2</a></p>
<p><a target="_blank" rel="noopener" href="https://blog.golangstack.com/post/go-mod-import-local-package/">go mod 导入本地包</a></p>
</blockquote>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2022/11/30/GCC%E5%8F%82%E6%95%B0%E8%AF%A6%E8%A7%A3/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2022/11/30/GCC%E5%8F%82%E6%95%B0%E8%AF%A6%E8%A7%A3/" class="post-title-link" itemprop="url">GCC参数详解</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>
      

      <time title="创建时间：2022-11-30 22:39:32 / 修改时间：22:45:59" itemprop="dateCreated datePublished" datetime="2022-11-30T22:39:32+08:00">2022-11-30</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/C/" itemprop="url" rel="index"><span itemprop="name">C</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h3 id="gcc工作步骤"><a href="#gcc工作步骤" class="headerlink" title="gcc工作步骤"></a>gcc工作步骤</h3><p>gcc 与 g++ 分别是 gnu 的 c &amp; c++ 编译器 gcc&#x2F;g++ 在执行编译工作的时候，总共需要4步：</p>
<ul>
<li>1、预处理,生成 .i 的文件[预处理器cpp]</li>
<li>2、将预处理后的文件转换成汇编语言, 生成文件 .s [编译器egcs]</li>
<li>3、有汇编变为目标代码(机器代码)生成 .o 的文件[汇编器as]</li>
<li>4、连接目标代码, 生成可执行程序 [链接器ld]</li>
</ul>
<h3 id="参数详解"><a href="#参数详解" class="headerlink" title="参数详解"></a>参数详解</h3><p><strong>-x language filename</strong></p>
<p>设定文件所使用的语言, 使后缀名无效, 对以后的多个有效。也就是根据约定 C 语言的后缀名称是 .c 的，而 C++ 的后缀名是 .C 或者 .cpp, 如果你很个性，决定你的 C 代码文件的后缀名是 .pig 哈哈，那你就要用这个参数, 这个参数对他后面的文件名都起作用，除非到了下一个参数的使用。 可以使用的参数吗有下面的这些：’c’, ‘objective-c’, ‘c-header’, ‘c++’, ‘cpp-output’, ‘assembler’, 与 ‘assembler-with-cpp’。</p>
<p>看到英文，应该可以理解的。</p>
<p>例子用法:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gcc -x c hello.pig </span><br></pre></td></tr></table></figure>

<p>　　</p>
<p><strong>-x none filename</strong></p>
<p>关掉上一个选项，也就是让gcc根据文件名后缀，自动识别文件类型 。</p>
<p>例子用法:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gcc -x c hello.pig -x none hello2.c </span><br></pre></td></tr></table></figure>

<p>　　</p>
<p><strong>-c</strong></p>
<p>只激活预处理,编译,和汇编,也就是他只把程序做成obj文件</p>
<p>例子用法:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gcc -c hello.c </span><br></pre></td></tr></table></figure>

<p>他将生成 .o 的 obj 文件</p>
<p><strong>-S</strong></p>
<p>只激活预处理和编译，就是指把文件编译成为汇编代码。</p>
<p>例子用法:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gcc -S hello.c </span><br></pre></td></tr></table></figure>

<p>他将生成 .s 的汇编代码，你可以用文本编辑器察看。</p>
<p><strong>-E</strong></p>
<p>只激活预处理,这个不生成文件, 你需要把它重定向到一个输出文件里面。</p>
<p>例子用法:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc -E hello.c &gt; pianoapan.txt </span><br><span class="line">gcc -E hello.c | more </span><br></pre></td></tr></table></figure>

<p>慢慢看吧, 一个 hello word 也要与处理成800行的代码。</p>
<p><strong>-o</strong></p>
<p>制定目标名称, 默认的时候, gcc 编译出来的文件是 a.out, 很难听, 如果你和我有同感，改掉它, 哈哈。</p>
<p>例子用法:</p>
<p>　　</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gcc -o hello.exe hello.c (哦,windows用习惯了) </span><br><span class="line">　　gcc -o hello.asm -S hello.c</span><br></pre></td></tr></table></figure>

<p><strong>-pipe</strong></p>
<p>　　</p>
<p>使用管道代替编译中临时文件, 在使用非 gnu 汇编工具的时候, 可能有些问题。</p>
<p>　　</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gcc -pipe -o hello.exe hello.c </span><br></pre></td></tr></table></figure>

<p><strong>-ansi</strong></p>
<p>关闭 gnu c中与 ansi c 不兼容的特性, 激活 ansi c 的专有特性（包括禁止一些 asm inline typeof 关键字, 以及 UNIX,vax 等预处理宏）。</p>
<p><strong>-fno-asm</strong></p>
<p>此选项实现 ansi 选项的功能的一部分，它禁止将 asm, inline 和 typeof 用作关键字。</p>
<p>　　　　</p>
<p><strong>-fno-strict-prototype</strong></p>
<p>只对 g++ 起作用, 使用这个选项, g++ 将对不带参数的函数,都认为是没有显式的对参数的个数和类型说明,而不是没有参数。</p>
<p>而 gcc 无论是否使用这个参数, 都将对没有带参数的函数, 认为城没有显式说明的类型。</p>
<p>　　</p>
<p><strong>-fthis-is-varialble</strong></p>
<p>就是向传统 c++ 看齐, 可以使用 this 当一般变量使用。</p>
<p>　　</p>
<p><strong>-fcond-mismatch</strong></p>
<p>允许条件表达式的第二和第三参数类型不匹配, 表达式的值将为 void 类型。</p>
<p>　　</p>
<p><strong>-funsigned-char 、-fno-signed-char、-fsigned-char 、-fno-unsigned-char</strong></p>
<p>这四个参数是对 char 类型进行设置, 决定将 char 类型设置成 unsigned char(前两个参数)或者 signed char(后两个参数)。</p>
<p>　　</p>
<p><strong>-include file</strong></p>
<p>包含某个代码,简单来说,就是便以某个文件,需要另一个文件的时候,就可以用它设定,功能就相当于在代码中使用 **#include<filename>**。</p>
<p>例子用法:</p>
<p>　　</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gcc hello.c -include /root/pianopan.h </span><br></pre></td></tr></table></figure>

<p>　　</p>
<p><strong>-imacros file</strong></p>
<p>　　</p>
<p>将 file 文件的宏, 扩展到 gcc&#x2F;g++ 的输入文件, 宏定义本身并不出现在输入文件中。</p>
<p>　　</p>
<p><strong>-Dmacro</strong></p>
<p>相当于 C 语言中的 <strong>#define macro</strong></p>
<p>　　</p>
<p><strong>-Dmacro&#x3D;defn</strong></p>
<p>相当于 C 语言中的 <strong>#define macro&#x3D;defn</strong></p>
<p>　　</p>
<p><strong>-Umacro</strong></p>
<p>相当于 C 语言中的 <strong>#undef macro</strong></p>
<p><strong>-undef</strong></p>
<p>　　</p>
<p>取消对任何非标准宏的定义</p>
<p>　　</p>
<p><strong>-Idir</strong></p>
<p>在你是用 <strong>#include “file”</strong> 的时候, gcc&#x2F;g++ 会先在当前目录查找你所制定的头文件, 如果没有找到, 他回到默认的头文件目录找, 如果使用 -I 制定了目录,他会先在你所制定的目录查找, 然后再按常规的顺序去找。</p>
<p>对于 #include<file>, gcc&#x2F;g++ 会到 -I 制定的目录查找, 查找不到, 然后将到系统的默认的头文件目录查找 。</p>
<p>　　</p>
<p><strong>-I-</strong></p>
<p>　　</p>
<p>就是取消前一个参数的功能, 所以一般在 -Idir 之后使用。</p>
<p>　　</p>
<p><strong>-idirafter dir</strong></p>
<p>在 -I 的目录里面查找失败, 讲到这个目录里面查找。</p>
<p>　　</p>
<p><strong>-iprefix prefix 、-iwithprefix dir</strong></p>
<p>一般一起使用, 当 -I 的目录查找失败, 会到 prefix+dir 下查找</p>
<p>　　</p>
<p><strong>-nostdinc</strong></p>
<p>　　</p>
<p>使编译器不再系统默认的头文件目录里面找头文件, 一般和 -I 联合使用,明确限定头文件的位置。</p>
<p>　　</p>
<p><strong>-nostdin C++</strong></p>
<p>　</p>
<p>规定不在 g++ 指定的标准路经中搜索, 但仍在其他路径中搜索, 此选项在创 libg++ 库使用 。</p>
<p>　　</p>
<p><strong>-C</strong></p>
<p>　</p>
<p>在预处理的时候, 不删除注释信息, 一般和-E使用, 有时候分析程序，用这个很方便的。</p>
<p>　　</p>
<p><strong>-M</strong></p>
<p>　</p>
<p>生成文件关联的信息。包含目标文件所依赖的所有源代码你可以用 <strong>gcc -M hello.c</strong> 来测试一下，很简单。</p>
<p>　　</p>
<p><strong>-MM</strong></p>
<p>　</p>
<p>和上面的那个一样，但是它将忽略由 <strong>#include<file></strong> 造成的依赖关系。 　　</p>
<p><strong>-MD</strong></p>
<p>　</p>
<p>和-M相同，但是输出将导入到.d的文件里面 　　</p>
<p><strong>-MMD</strong></p>
<p>　</p>
<p>和 -MM 相同，但是输出将导入到 .d 的文件里面。</p>
<p>　　</p>
<p><strong>-Wa,option</strong></p>
<p>　</p>
<p>此选项传递 option 给汇编程序; 如果 option 中间有逗号, 就将 option 分成多个选项, 然 后传递给会汇编程序。</p>
<p>　　</p>
<p><strong>-Wl.option</strong></p>
<p>　</p>
<p>此选项传递 option 给连接程序; 如果 option 中间有逗号, 就将 option 分成多个选项, 然 后传递给会连接程序。</p>
<p>　　</p>
<p><strong>-llibrary</strong></p>
<p>　</p>
<p>制定编译的时候使用的库</p>
<p>　　</p>
<p>例子用法</p>
<p>　　</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gcc -lcurses hello.c</span><br></pre></td></tr></table></figure>

<p>　　</p>
<p>使用 ncurses 库编译程序</p>
<p>　　</p>
<p><strong>-Ldir</strong></p>
<p>　　</p>
<p>制定编译的时候，搜索库的路径。比如你自己的库，可以用它制定目录，不然编译器将只在标准库的目录找。这个dir就是目录的名称。</p>
<p>　　</p>
<p><strong>-O0 、-O1 、-O2 、-O3</strong></p>
<p>　　</p>
<p>编译器的优化选项的 4 个级别，-O0 表示没有优化, -O1 为默认值，-O3 优化级别最高。</p>
<p>　 　 　　</p>
<p><strong>-g</strong></p>
<p>　　</p>
<p>只是编译器，在编译的时候，产生调试信息。</p>
<p>　　</p>
<p><strong>-gstabs</strong></p>
<p>　　</p>
<p>此选项以 stabs 格式声称调试信息, 但是不包括 gdb 调试信息。</p>
<p>　　</p>
<p><strong>-gstabs+</strong></p>
<p>　　</p>
<p>此选项以 stabs 格式声称调试信息, 并且包含仅供 gdb 使用的额外调试信息。</p>
<p>　　</p>
<p><strong>-ggdb</strong></p>
<p>　　</p>
<p>此选项将尽可能的生成 gdb 的可以使用的调试信息。</p>
<p><strong>-static</strong></p>
<p>　　</p>
<p>此选项将禁止使用动态库，所以，编译出来的东西，一般都很大，也不需要什么动态连接库，就可以运行。</p>
<p><strong>-share</strong></p>
<p>　</p>
<p>此选项将尽量使用动态库，所以生成文件比较小，但是需要系统由动态库。</p>
<p><strong>-traditional</strong></p>
<p>　　</p>
<p>试图让编译器支持传统的C语言特性。</p>
<p>GCC 是 GNU 的 C 和 C++ 编译器。实际上，GCC 能够编译三种语言：C、C++ 和 Object C（C 语言的一种面向对象扩展）。利用 gcc 命令可同时编译并连接 C 和 C++ 源程序。</p>
<p>如果你有两个或少数几个 C 源文件，也可以方便地利用 GCC 编译、连接并生成可执行文件。例如，假设你有两个源文件 main.c 和 factorial.c 两个源文件，现在要编 译生成一个计算阶乘的程序。</p>
<p>factorial.c 文件代码</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="title function_">factorial</span><span class="params">(<span class="type">int</span> n)</span> &#123;</span><br><span class="line">    <span class="keyword">if</span> (n &lt;= <span class="number">1</span>) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">else</span> <span class="keyword">return</span> factorial(n - <span class="number">1</span>) * n;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>main.c 文件代码</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;stdio.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string">&lt;unistd.h&gt;</span></span></span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">factorial</span><span class="params">(<span class="type">int</span> n)</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> **argv)</span> &#123;</span><br><span class="line">    <span class="type">int</span> n;</span><br><span class="line">    <span class="keyword">if</span> (argc &lt; <span class="number">2</span>) &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;Usage: %s n\n&quot;</span>, argv[<span class="number">0</span>]);  <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line">    &#125;  <span class="keyword">else</span>  &#123;</span><br><span class="line">        n = atoi(argv[<span class="number">1</span>]);  <span class="built_in">printf</span>(<span class="string">&quot;Factorial of %d is %d.\n&quot;</span>, n, factorial(n));</span><br><span class="line">    &#125; </span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>利用如下的命令可编译生成可执行文件，并执行程序：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">gcc -o factorial main.c factorial.c</span> </span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">./factorial 5</span> </span><br><span class="line">Factorial of 5 is 120. </span><br></pre></td></tr></table></figure>

<p>GCC 可同时用来编译 C 程序和 C++ 程序。一般来说，C 编译器通过源文件的后缀名来判断是 C 程序还是 C++ 程序。在 Linux 中，C 源文件的后缀名为 .c，而 C++ 源文件的后缀名为 .C 或 .cpp。但是，gcc 命令只能编译 C++ 源文件，而不能自动和 C++ 程序使用的库连接。因此，通常使用 g++ 命令来完成 C++ 程序的编译和连接，该程序会自动调用 gcc 实现编译。假设我们有一个如下的 C++ 源文件（hello.c）：</p>
<p>hello.c 文件代码</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string">&lt;iostream&gt;</span>  void main (void)  &#123;  　cout &lt;&lt; <span class="string">&quot;Hello, world!&quot;</span> &lt;&lt; endl;  &#125;</span></span><br></pre></td></tr></table></figure>

<p>则可以如下调用 g++ 命令编译、连接并生成可执行文件：</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">g++ -o hello hello.c</span> </span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">./hello</span> </span><br><span class="line">Hello, world! </span><br></pre></td></tr></table></figure>

<h3 id="gcc-命令的常用选项"><a href="#gcc-命令的常用选项" class="headerlink" title="gcc 命令的常用选项"></a>gcc 命令的常用选项</h3><table>
<thead>
<tr>
<th align="left">选项</th>
<th align="left">解释</th>
</tr>
</thead>
<tbody><tr>
<td align="left">-ansi</td>
<td align="left">只支持 ANSI 标准的 C 语法。这一选项将禁止 GNU C 的某些特色， 例如 asm 或 typeof 关键词。</td>
</tr>
<tr>
<td align="left">-c</td>
<td align="left">只编译并生成目标文件。</td>
</tr>
<tr>
<td align="left">-DMACRO</td>
<td align="left">以字符串”1”定义 MACRO 宏。</td>
</tr>
<tr>
<td align="left">-DMACRO&#x3D;DEFN</td>
<td align="left">以字符串”DEFN”定义 MACRO 宏。</td>
</tr>
<tr>
<td align="left">-E</td>
<td align="left">只运行 C 预编译器。</td>
</tr>
<tr>
<td align="left">-g</td>
<td align="left">生成调试信息。GNU 调试器可利用该信息。</td>
</tr>
<tr>
<td align="left">-IDIRECTORY</td>
<td align="left">指定额外的头文件搜索路径DIRECTORY。</td>
</tr>
<tr>
<td align="left">-LDIRECTORY</td>
<td align="left">指定额外的函数库搜索路径DIRECTORY。</td>
</tr>
<tr>
<td align="left">-lLIBRARY</td>
<td align="left">连接时搜索指定的函数库LIBRARY。</td>
</tr>
<tr>
<td align="left">-m486</td>
<td align="left">针对 486 进行代码优化。</td>
</tr>
<tr>
<td align="left">-o FILE</td>
<td align="left">生成指定的输出文件。用在生成可执行文件时。</td>
</tr>
<tr>
<td align="left">-O0</td>
<td align="left">不进行优化处理。</td>
</tr>
<tr>
<td align="left">-O 或 -O1</td>
<td align="left">优化生成代码。</td>
</tr>
<tr>
<td align="left">-O2</td>
<td align="left">进一步优化。</td>
</tr>
<tr>
<td align="left">-O3</td>
<td align="left">比 -O2 更进一步优化，包括 inline 函数。</td>
</tr>
<tr>
<td align="left">-shared</td>
<td align="left">生成共享目标文件。通常用在建立共享库时。</td>
</tr>
<tr>
<td align="left">-static</td>
<td align="left">禁止使用共享连接。</td>
</tr>
<tr>
<td align="left">-UMACRO</td>
<td align="left">取消对 MACRO 宏的定义。</td>
</tr>
<tr>
<td align="left">-w</td>
<td align="left">不生成任何警告信息。</td>
</tr>
<tr>
<td align="left">-Wall</td>
<td align="left">生成所有警告信息。</td>
</tr>
</tbody></table>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2022/11/30/GoLang-Cgo/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2022/11/30/GoLang-Cgo/" class="post-title-link" itemprop="url">GoLang-Cgo</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>
      

      <time title="创建时间：2022-11-30 22:27:44 / 修改时间：22:28:14" itemprop="dateCreated datePublished" datetime="2022-11-30T22:27:44+08:00">2022-11-30</time>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <p><a target="_blank" rel="noopener" href="https://bastengao.com/blog/2017/12/go-cgo-c.html">https://bastengao.com/blog/2017/12/go-cgo-c.html</a></p>
<p><a target="_blank" rel="noopener" href="https://go.dev/blog/cgo">https://go.dev/blog/cgo</a></p>
<p><a target="_blank" rel="noopener" href="https://pkg.go.dev/cmd/cgo">https://pkg.go.dev/cmd/cgo</a></p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2022/11/30/GoLang-Channel/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2022/11/30/GoLang-Channel/" class="post-title-link" itemprop="url">GoLang-Channel</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>
      

      <time title="创建时间：2022-11-30 15:36:30 / 修改时间：23:34:25" itemprop="dateCreated datePublished" datetime="2022-11-30T15:36:30+08:00">2022-11-30</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Go/" itemprop="url" rel="index"><span itemprop="name">Go</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="使用channel构建信号量"><a href="#使用channel构建信号量" class="headerlink" title="使用channel构建信号量"></a>使用channel构建信号量</h1><h2 id="与Java中Semaphore的差别"><a href="#与Java中Semaphore的差别" class="headerlink" title="与Java中Semaphore的差别"></a>与Java中Semaphore的差别</h2>
      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2022/11/30/LeetCode%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B%E9%A2%98/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2022/11/30/LeetCode%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B%E9%A2%98/" class="post-title-link" itemprop="url">LeetCode并发编程题</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>
      

      <time title="创建时间：2022-11-30 02:33:13 / 修改时间：19:51:55" itemprop="dateCreated datePublished" datetime="2022-11-30T02:33:13+08:00">2022-11-30</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/" itemprop="url" rel="index"><span itemprop="name">并发编程</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <h1 id="1114-按序打印"><a href="#1114-按序打印" class="headerlink" title="1114. 按序打印"></a>1114. 按序打印</h1><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> java.util.concurrent.locks.Condition;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.locks.Lock;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.locks.ReentrantLock;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Foo</span> &#123;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="type">Lock</span> <span class="variable">lock</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ReentrantLock</span>();</span><br><span class="line"></span><br><span class="line">    <span class="type">boolean</span> <span class="variable">firstFinished</span> <span class="operator">=</span> <span class="literal">false</span>;</span><br><span class="line">    <span class="type">Condition</span> <span class="variable">firstCondition</span> <span class="operator">=</span> lock.newCondition();</span><br><span class="line"></span><br><span class="line">    <span class="type">boolean</span> <span class="variable">secondFinished</span> <span class="operator">=</span> <span class="literal">false</span>;</span><br><span class="line">    <span class="type">Condition</span> <span class="variable">secondCondition</span> <span class="operator">=</span> lock.newCondition();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">Foo</span><span class="params">()</span> &#123;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">first</span><span class="params">(Runnable printFirst)</span> <span class="keyword">throws</span> InterruptedException &#123;</span><br><span class="line">        lock.lock();</span><br><span class="line">        <span class="comment">// printFirst.run() outputs &quot;first&quot;. Do not change or remove this line.</span></span><br><span class="line">        printFirst.run();</span><br><span class="line">        firstCondition.signal();</span><br><span class="line">        firstFinished = <span class="literal">true</span>;</span><br><span class="line">        lock.unlock();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">second</span><span class="params">(Runnable printSecond)</span> <span class="keyword">throws</span> InterruptedException &#123;</span><br><span class="line">        lock.lock();</span><br><span class="line">        <span class="keyword">if</span>(!firstFinished)&#123;</span><br><span class="line">            firstCondition.await();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// printSecond.run() outputs &quot;second&quot;. Do not change or remove this line.</span></span><br><span class="line">        printSecond.run();</span><br><span class="line">        secondCondition.signal();</span><br><span class="line">        secondFinished = <span class="literal">true</span>;</span><br><span class="line">        lock.unlock();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">third</span><span class="params">(Runnable printThird)</span> <span class="keyword">throws</span> InterruptedException &#123;</span><br><span class="line">        lock.lock();</span><br><span class="line">        <span class="keyword">if</span>(!secondFinished) &#123;</span><br><span class="line">            secondCondition.await();</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">// printThird.run() outputs &quot;third&quot;. Do not change or remove this line.</span></span><br><span class="line">        printThird.run();</span><br><span class="line">        lock.unlock();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line">	<span class="string">&quot;sync&quot;</span></span><br><span class="line">	<span class="string">&quot;time&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> Foo <span class="keyword">struct</span> &#123;</span><br><span class="line">	firstReady  <span class="keyword">chan</span> <span class="keyword">struct</span>&#123;&#125;</span><br><span class="line">	secondReady <span class="keyword">chan</span> <span class="keyword">struct</span>&#123;&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">newFoo</span><span class="params">()</span></span> *Foo &#123;</span><br><span class="line">	<span class="keyword">return</span> &amp;Foo&#123;</span><br><span class="line">		firstReady:  <span class="built_in">make</span>(<span class="keyword">chan</span> <span class="keyword">struct</span>&#123;&#125;),</span><br><span class="line">		secondReady: <span class="built_in">make</span>(<span class="keyword">chan</span> <span class="keyword">struct</span>&#123;&#125;),</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(foo *Foo)</span></span> first() &#123;</span><br><span class="line">	<span class="built_in">println</span>(<span class="string">&quot;first&quot;</span>)</span><br><span class="line">	foo.firstReady &lt;- <span class="keyword">struct</span>&#123;&#125;&#123;&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(foo *Foo)</span></span> second() &#123;</span><br><span class="line">	&lt;-foo.firstReady</span><br><span class="line">	<span class="built_in">println</span>(<span class="string">&quot;second&quot;</span>)</span><br><span class="line">	foo.secondReady &lt;- <span class="keyword">struct</span>&#123;&#125;&#123;&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(foo *Foo)</span></span> third() &#123;</span><br><span class="line">	&lt;-foo.secondReady</span><br><span class="line">	<span class="built_in">println</span>(<span class="string">&quot;third&quot;</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">solve</span><span class="params">(foo *Foo)</span></span> &#123;</span><br><span class="line">	wg := sync.WaitGroup&#123;&#125;</span><br><span class="line">	wg.Add(<span class="number">3</span>)</span><br><span class="line"></span><br><span class="line">	<span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">		<span class="keyword">defer</span> wg.Done()</span><br><span class="line">		foo.third()</span><br><span class="line">	&#125;()</span><br><span class="line"></span><br><span class="line">	<span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">		<span class="keyword">defer</span> wg.Done()</span><br><span class="line">		foo.second()</span><br><span class="line">	&#125;()</span><br><span class="line"></span><br><span class="line">	<span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">		<span class="keyword">defer</span> wg.Done()</span><br><span class="line">		foo.first()</span><br><span class="line">	&#125;()</span><br><span class="line"></span><br><span class="line">	wg.Wait()</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">	<span class="keyword">for</span> &#123;</span><br><span class="line">		foo := newFoo()</span><br><span class="line">		solve(foo)</span><br><span class="line">		<span class="built_in">println</span>()</span><br><span class="line">		time.Sleep(time.Second)</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>





<h1 id="1117-H2O-生成"><a href="#1117-H2O-生成" class="headerlink" title="1117. H2O 生成"></a>1117. H2O 生成</h1><p><a target="_blank" rel="noopener" href="https://leetcode.cn/problems/building-h2o/">https://leetcode.cn/problems/building-h2o/</a></p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> java.util.concurrent.locks.Condition;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.locks.Lock;</span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.locks.ReentrantLock;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">H2O</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="type">Lock</span> <span class="variable">lock</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ReentrantLock</span>();</span><br><span class="line"></span><br><span class="line">    <span class="type">int</span> numOfO;</span><br><span class="line">    <span class="type">int</span> numOfH; </span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="type">Condition</span> <span class="variable">oCondition</span> <span class="operator">=</span> lock.newCondition();</span><br><span class="line">    <span class="type">Condition</span> <span class="variable">hCondition</span> <span class="operator">=</span> lock.newCondition();</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">H2O</span><span class="params">()</span> &#123;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="type">boolean</span> <span class="title function_">ableGenerate</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> numOfO == <span class="number">1</span> &amp;&amp; numOfH == <span class="number">2</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">reset</span><span class="params">()</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.numOfO = <span class="built_in">this</span>.numOfH = <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">hydrogen</span><span class="params">(Runnable releaseHydrogen)</span> <span class="keyword">throws</span> InterruptedException &#123;</span><br><span class="line">        lock.lock();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">while</span> (numOfH == <span class="number">2</span>) &#123;</span><br><span class="line">                hCondition.await();</span><br><span class="line">            &#125;</span><br><span class="line">            numOfH++;</span><br><span class="line">            releaseHydrogen.run();</span><br><span class="line">            <span class="keyword">if</span> (ableGenerate()) &#123;</span><br><span class="line">                reset();</span><br><span class="line">                oCondition.signalAll();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            lock.unlock();</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">oxygen</span><span class="params">(Runnable releaseOxygen)</span> <span class="keyword">throws</span> InterruptedException &#123;</span><br><span class="line">        lock.lock();</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="keyword">while</span> (numOfO == <span class="number">1</span>) &#123;</span><br><span class="line">                oCondition.await();</span><br><span class="line">            &#125;</span><br><span class="line">            releaseOxygen.run();</span><br><span class="line">            numOfO++;</span><br><span class="line">            <span class="keyword">if</span> (ableGenerate()) &#123;</span><br><span class="line">                reset();</span><br><span class="line">                hCondition.signalAll();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">finally</span> &#123;</span><br><span class="line">            lock.unlock();</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line">	<span class="string">&quot;fmt&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> (</span><br><span class="line">	H = <span class="string">&quot;h&quot;</span></span><br><span class="line">	O = <span class="string">&quot;o&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> H2OGenerator <span class="keyword">struct</span> &#123;</span><br><span class="line">	hydrogen <span class="keyword">chan</span> <span class="type">string</span></span><br><span class="line">	oxygen   <span class="keyword">chan</span> <span class="type">string</span></span><br><span class="line">	h2o      <span class="keyword">chan</span> <span class="type">string</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">newH2OGenerator</span><span class="params">()</span></span> *H2OGenerator &#123;</span><br><span class="line">	<span class="keyword">return</span> &amp;H2OGenerator&#123;</span><br><span class="line">		hydrogen: <span class="built_in">make</span>(<span class="keyword">chan</span> <span class="type">string</span>, <span class="number">2</span>),</span><br><span class="line">		oxygen:   <span class="built_in">make</span>(<span class="keyword">chan</span> <span class="type">string</span>, <span class="number">1</span>),</span><br><span class="line">		h2o:      <span class="built_in">make</span>(<span class="keyword">chan</span> <span class="type">string</span>, <span class="number">3</span>), <span class="comment">// this cap only must be greater than or equal 3</span></span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(g *H2OGenerator)</span></span> GeneratorH2O() &#123;</span><br><span class="line">	<span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">		<span class="keyword">for</span> &#123;</span><br><span class="line">			g.hydrogen &lt;- H</span><br><span class="line">			g.h2o &lt;- H</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;()</span><br><span class="line"></span><br><span class="line">	<span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">		<span class="keyword">for</span> &#123;</span><br><span class="line">			g.oxygen &lt;- O</span><br><span class="line">			g.h2o &lt;- O</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;()</span><br><span class="line"></span><br><span class="line">	h20Flow := <span class="built_in">make</span>(<span class="keyword">chan</span> <span class="type">string</span>)</span><br><span class="line"></span><br><span class="line">	<span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">		<span class="keyword">for</span> &#123;</span><br><span class="line">			res := <span class="string">&quot;&quot;</span></span><br><span class="line">			<span class="keyword">for</span> i := <span class="number">0</span>; i &lt; <span class="number">3</span>; i++ &#123;</span><br><span class="line">				res += &lt;-g.h2o</span><br><span class="line">			&#125;</span><br><span class="line">			h20Flow &lt;- res</span><br><span class="line">			&lt;-g.hydrogen</span><br><span class="line">			&lt;-g.hydrogen</span><br><span class="line">			&lt;-g.oxygen</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;()</span><br><span class="line"></span><br><span class="line">	<span class="comment">// checker</span></span><br><span class="line">	<span class="function"><span class="keyword">func</span><span class="params">(flow &lt;-<span class="keyword">chan</span> <span class="type">string</span>)</span></span> &#123;</span><br><span class="line">		ok := <span class="function"><span class="keyword">func</span><span class="params">(s <span class="type">string</span>)</span></span> <span class="type">bool</span> &#123;</span><br><span class="line">			<span class="keyword">var</span> hCounter, oCounter <span class="type">int</span></span><br><span class="line">			<span class="keyword">for</span> _, c := <span class="keyword">range</span> s &#123;</span><br><span class="line">				<span class="keyword">if</span> c == <span class="string">&#x27;h&#x27;</span> &#123;</span><br><span class="line">					hCounter++</span><br><span class="line">				&#125; <span class="keyword">else</span> <span class="keyword">if</span> c == <span class="string">&#x27;o&#x27;</span> &#123;</span><br><span class="line">					oCounter++</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="keyword">return</span> hCounter == <span class="number">2</span> &amp;&amp; oCounter == <span class="number">1</span></span><br><span class="line">		&#125;</span><br><span class="line"></span><br><span class="line">		<span class="keyword">for</span> e := <span class="keyword">range</span> flow &#123;</span><br><span class="line">			<span class="keyword">if</span> ok(e) &#123;</span><br><span class="line">				<span class="comment">//fmt.Println(e)</span></span><br><span class="line">			&#125; <span class="keyword">else</span> &#123;</span><br><span class="line">				<span class="built_in">panic</span>(fmt.Sprintf(<span class="string">&quot;h20-generator working wrong, res = %s&quot;</span>, e))</span><br><span class="line">			&#125;</span><br><span class="line">			<span class="comment">//time.Sleep(time.Second)</span></span><br><span class="line">		&#125;</span><br><span class="line">	&#125;(h20Flow)</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">	newH2OGenerator().GeneratorH2O()</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>



<p>3个channel实际上就是3个信号量，向channel里发送元素实际上对应信号量的acquire，接收元素对应release。</p>
<p>这3个信号量的操作顺序实际上就是并发屏障。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">S1 = Semaphore(1)</span><br><span class="line">S2 = Semaphore(2)</span><br><span class="line">S3 = Semaphore(3)</span><br><span class="line"></span><br><span class="line">goroutine1 -&gt; &#123;</span><br><span class="line">    S1.P()</span><br><span class="line">    S3.P()</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">goroutine2 -&gt; &#123;</span><br><span class="line">    S2.P()</span><br><span class="line">    S3.P()</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">goroutine3 -&gt; &#123;</span><br><span class="line">    S3.V()</span><br><span class="line">    S3.V()</span><br><span class="line">    S3.V()</span><br><span class="line">    </span><br><span class="line">    S1.V()</span><br><span class="line">    S2.V()</span><br><span class="line">    S2.V()</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>


<blockquote>
<p>注意，这里使用channel实现的信号量的V操作和java中的Semaphore的release操作语义不一致！</p>
</blockquote>
<h1 id="1115-交替打印-FooBar"><a href="#1115-交替打印-FooBar" class="headerlink" title="1115. 交替打印 FooBar"></a>1115. 交替打印 FooBar</h1><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">FooBar</span> &#123;</span><br><span class="line">    <span class="keyword">private</span> <span class="type">int</span> n;</span><br><span class="line"></span><br><span class="line">    <span class="type">boolean</span> <span class="variable">available</span> <span class="operator">=</span> <span class="literal">false</span>;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="title function_">FooBar</span><span class="params">(<span class="type">int</span> n)</span> &#123;</span><br><span class="line">        <span class="built_in">this</span>.n = n;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">foo</span><span class="params">(Runnable printFoo)</span> <span class="keyword">throws</span> InterruptedException &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">            <span class="keyword">synchronized</span> (<span class="built_in">this</span>) &#123;</span><br><span class="line">                <span class="keyword">if</span> (available) &#123;</span><br><span class="line">                    <span class="built_in">this</span>.wait();</span><br><span class="line">                &#125;</span><br><span class="line">                printFoo.run();</span><br><span class="line">                <span class="built_in">this</span>.notify();</span><br><span class="line">                <span class="built_in">this</span>.available = !<span class="built_in">this</span>.available;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">bar</span><span class="params">(Runnable printBar)</span> <span class="keyword">throws</span> InterruptedException &#123;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i &lt; n; i++) &#123;</span><br><span class="line">            <span class="keyword">synchronized</span> (<span class="built_in">this</span>) &#123;</span><br><span class="line">                <span class="keyword">if</span> (!available) &#123;</span><br><span class="line">                    <span class="built_in">this</span>.wait();</span><br><span class="line">                &#125;</span><br><span class="line">                printBar.run();</span><br><span class="line">                <span class="built_in">this</span>.notify();</span><br><span class="line">                <span class="built_in">this</span>.available = !<span class="built_in">this</span>.available;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line">	<span class="string">&quot;sync&quot;</span></span><br><span class="line">	<span class="string">&quot;time&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> FooBar <span class="keyword">struct</span> &#123;</span><br><span class="line">	n        <span class="type">int</span></span><br><span class="line">	fooReady <span class="keyword">chan</span> <span class="keyword">struct</span>&#123;&#125;</span><br><span class="line">	barReady <span class="keyword">chan</span> <span class="keyword">struct</span>&#123;&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">newFooBar</span><span class="params">(n <span class="type">int</span>)</span></span> *FooBar &#123;</span><br><span class="line">	<span class="keyword">return</span> &amp;FooBar&#123;</span><br><span class="line">		n:        n,</span><br><span class="line">		fooReady: <span class="built_in">make</span>(<span class="keyword">chan</span> <span class="keyword">struct</span>&#123;&#125;),</span><br><span class="line">		barReady: <span class="built_in">make</span>(<span class="keyword">chan</span> <span class="keyword">struct</span>&#123;&#125;),</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(fooBar *FooBar)</span></span> foo() &#123;</span><br><span class="line">	<span class="keyword">for</span> i := <span class="number">0</span>; i &lt; fooBar.n; i++ &#123;</span><br><span class="line">		&lt;-fooBar.fooReady</span><br><span class="line">		<span class="built_in">print</span>(<span class="string">&quot;foo&quot;</span>)</span><br><span class="line">		fooBar.barReady &lt;- <span class="keyword">struct</span>&#123;&#125;&#123;&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(fooBar *FooBar)</span></span> bar() &#123;</span><br><span class="line">	<span class="keyword">for</span> i := <span class="number">0</span>; i &lt; fooBar.n; i++ &#123;</span><br><span class="line">		&lt;-fooBar.barReady</span><br><span class="line">		<span class="built_in">print</span>(<span class="string">&quot;bar&quot;</span>)</span><br><span class="line">		<span class="keyword">if</span> i != fooBar.n<span class="number">-1</span> &#123; <span class="comment">// notice sync channel&#x27;s feature, receive must match send</span></span><br><span class="line">			fooBar.fooReady &lt;- <span class="keyword">struct</span>&#123;&#125;&#123;&#125;</span><br><span class="line">		&#125;</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">solve</span><span class="params">(fooBar *FooBar)</span></span> &#123;</span><br><span class="line">	wg := sync.WaitGroup&#123;&#125;</span><br><span class="line">	wg.Add(<span class="number">2</span>)</span><br><span class="line">	<span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">		<span class="keyword">defer</span> wg.Done()</span><br><span class="line">		fooBar.bar()</span><br><span class="line">	&#125;()</span><br><span class="line"></span><br><span class="line">	<span class="keyword">go</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">		<span class="keyword">defer</span> wg.Done()</span><br><span class="line">		fooBar.foo()</span><br><span class="line">	&#125;()</span><br><span class="line"></span><br><span class="line">	fooBar.fooReady &lt;- <span class="keyword">struct</span>&#123;&#125;&#123;&#125;</span><br><span class="line">	wg.Wait()</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">	<span class="keyword">for</span> &#123;</span><br><span class="line">		foo := newFooBar(<span class="number">10</span>)</span><br><span class="line">		solve(foo)</span><br><span class="line">		<span class="built_in">println</span>()</span><br><span class="line">		time.Sleep(time.Second)</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>
      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2022/11/30/GoLang-%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2022/11/30/GoLang-%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86/" class="post-title-link" itemprop="url">GoLang-错误处理</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2022-11-30 00:06:14" itemprop="dateCreated datePublished" datetime="2022-11-30T00:06:14+08:00">2022-11-30</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2022-12-04 19:33:47" itemprop="dateModified" datetime="2022-12-04T19:33:47+08:00">2022-12-04</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Go/" itemprop="url" rel="index"><span itemprop="name">Go</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line">	<span class="string">&quot;sync&quot;</span></span><br><span class="line">	<span class="string">&quot;time&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> wg sync.WaitGroup</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">testPanic</span><span class="params">()</span></span> &#123;</span><br><span class="line">	a := []<span class="type">int</span>&#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>&#125;</span><br><span class="line">	<span class="built_in">println</span>(a[<span class="number">5</span>])</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// other&#x27;s code, maybe panic</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">boringTask</span><span class="params">(i <span class="type">int</span>)</span></span> &#123;</span><br><span class="line">	<span class="keyword">defer</span> wg.Done()</span><br><span class="line">	time.Sleep(time.Second * time.Duration(i))</span><br><span class="line">	<span class="keyword">if</span> i == <span class="number">2</span> &#123;</span><br><span class="line">		testPanic()</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="built_in">println</span>(<span class="string">&quot;end:&quot;</span>, i)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">	tasks := <span class="number">5</span></span><br><span class="line">	wg.Add(tasks)</span><br><span class="line">	<span class="keyword">for</span> i := <span class="number">0</span>; i &lt; tasks; i++ &#123;</span><br><span class="line">		<span class="keyword">go</span> boringTask(i)</span><br><span class="line">	&#125;</span><br><span class="line">	wg.Wait()</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>





<p>错误的做法：</p>
<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">	tasks := <span class="number">5</span></span><br><span class="line">	wg.Add(tasks)</span><br><span class="line">	<span class="keyword">for</span> i := <span class="number">0</span>; i &lt; tasks; i++ &#123;</span><br><span class="line">		<span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">			<span class="keyword">defer</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">				<span class="keyword">if</span> err := <span class="built_in">recover</span>(); err != <span class="literal">nil</span> &#123;</span><br><span class="line">					fmt.Printf(<span class="string">&quot;err=%v\n&quot;</span>, err)</span><br><span class="line">				&#125;</span><br><span class="line">			&#125;()</span><br><span class="line">			<span class="keyword">go</span> boringTask(i)</span><br><span class="line">		&#125;()</span><br><span class="line">	&#125;</span><br><span class="line">	wg.Wait()</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>





<figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line">	<span class="string">&quot;fmt&quot;</span></span><br><span class="line">	<span class="string">&quot;sync&quot;</span></span><br><span class="line">	<span class="string">&quot;time&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> wg sync.WaitGroup</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">testPanic</span><span class="params">()</span></span> &#123;</span><br><span class="line">	a := []<span class="type">int</span>&#123;<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>&#125;</span><br><span class="line">	<span class="built_in">println</span>(a[<span class="number">5</span>])</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// other&#x27;s code, maybe panic</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">boringTask</span><span class="params">(param <span class="type">int</span>)</span></span> &#123;</span><br><span class="line">	<span class="keyword">defer</span> wg.Done()</span><br><span class="line">	time.Sleep(time.Second * time.Duration(param))</span><br><span class="line">	<span class="keyword">if</span> param == <span class="number">2</span> &#123;</span><br><span class="line">		testPanic()</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="built_in">println</span>(<span class="string">&quot;end:&quot;</span>, param)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 自己包裹一下</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">boringTaskWrapper</span><span class="params">(param <span class="type">int</span>)</span></span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">	<span class="keyword">return</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">		<span class="keyword">defer</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> &#123;</span><br><span class="line">			<span class="keyword">if</span> err := <span class="built_in">recover</span>(); err != <span class="literal">nil</span> &#123;</span><br><span class="line">				fmt.Printf(<span class="string">&quot;err=%v\n&quot;</span>, err)</span><br><span class="line">			&#125;</span><br><span class="line">		&#125;()</span><br><span class="line">		boringTask(param)</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">	tasks := <span class="number">5</span></span><br><span class="line">	wg.Add(tasks)</span><br><span class="line">	<span class="keyword">for</span> i := <span class="number">0</span>; i &lt; tasks; i++ &#123;</span><br><span class="line">		<span class="keyword">go</span> boringTaskWrapper(i)()</span><br><span class="line">	&#125;</span><br><span class="line">	wg.Wait()</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>


      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2022/11/29/GoLang-%E6%8E%A5%E5%8F%A3/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="SongyangJi">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="JsyBlog">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="undefined | JsyBlog">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2022/11/29/GoLang-%E6%8E%A5%E5%8F%A3/" class="post-title-link" itemprop="url">GoLang-接口</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2022-11-29 02:04:22" itemprop="dateCreated datePublished" datetime="2022-11-29T02:04:22+08:00">2022-11-29</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar-check"></i>
      </span>
      <span class="post-meta-item-text">更新于</span>
      <time title="修改时间：2022-12-04 19:33:45" itemprop="dateModified" datetime="2022-12-04T19:33:45+08:00">2022-12-04</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/Go/" itemprop="url" rel="index"><span itemprop="name">Go</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> FormatError <span class="keyword">struct</span> &#123;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="params">(*FormatError)</span></span> Error() <span class="type">string</span> &#123;</span><br><span class="line">	<span class="keyword">return</span> <span class="string">&quot;format error&quot;</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line">	<span class="keyword">var</span> fe *FormatError = <span class="literal">nil</span></span><br><span class="line">	<span class="keyword">if</span> fe != <span class="literal">nil</span> &#123;</span><br><span class="line">		<span class="built_in">panic</span>(<span class="string">&quot;to 1&quot;</span>)</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="keyword">var</span> e <span class="type">error</span> = fe</span><br><span class="line">	<span class="keyword">if</span> e != <span class="literal">nil</span> &#123;</span><br><span class="line">		<span class="built_in">panic</span>(<span class="string">&quot;to 2&quot;</span>)</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>


      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




  <nav class="pagination">
    <a class="extend prev" rel="prev" title="上一页" aria-label="上一页" href="/page/3/"><i class="fa fa-angle-left"></i></a><a class="page-number" href="/">1</a><span class="space">&hellip;</span><a class="page-number" href="/page/3/">3</a><span class="page-number current">4</span><a class="page-number" href="/page/5/">5</a><span class="space">&hellip;</span><a class="page-number" href="/page/26/">26</a><a class="extend next" rel="next" title="下一页" aria-label="下一页" href="/page/5/"><i class="fa fa-angle-right"></i></a>
  </nav>

</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 
  <span itemprop="copyrightYear">2023</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">SongyangJi</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/muse/" rel="noopener" target="_blank">NexT.Muse</a> 强力驱动
  </div>

    </div>
  </footer>

  
  <div class="toggle sidebar-toggle" role="button">
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
  </div>
  <div class="sidebar-dimmer"></div>
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up fa-lg"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/schemes/muse.js"></script><script src="/js/next-boot.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/hexo-generator-searchdb/1.4.1/search.js" integrity="sha256-1kfA5uHPf65M5cphT2dvymhkuyHPQp5A53EGZOnOLmc=" crossorigin="anonymous"></script>
<script src="/js/third-party/search/local-search.js"></script>





  





</body>
</html>
